package cn.engage.basic.service.impl;

import cn.engage.basic.config.BussinessException;
import cn.engage.basic.constant.BaseConstant;
import cn.engage.basic.dto.MailCodeDto;
import cn.engage.basic.dto.PhoneSmsCodeDto;
import cn.engage.basic.service.VerifyCodeService;
import cn.engage.basic.util.EmailUtil;
import cn.engage.basic.util.StrUtils;
import cn.engage.basic.util.VerifyCodeUtils;
import cn.engage.user.domain.Logininfo;
import cn.engage.user.mapper.LogininfoMapper;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

/**
 * 获取图形验证码
 */
@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LogininfoMapper logininfoMapper;

    // 获取图形验证码
    @Override
    public String getVerifyCode(String uuidKey) {
        // 生产四位的随机数
        String randomString = StrUtils.getComplexRandomString(4);
        // 存入redis，设置存在redis的时间为3分钟
        redisTemplate.opsForValue().set(uuidKey,randomString,3, TimeUnit.MINUTES);
        // 返回给前端图形验证码调用VerifyCodeUtils
        return VerifyCodeUtils.VerifyCode(100,35,randomString);
    }
    // 手机注册发送验证码
    @Override
    public void smsCode(PhoneSmsCodeDto dto) {
        // 验证手机号格式是否正确
        if(!Pattern.matches("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",dto.getPhone())){
            throw new BussinessException("手机号格式错误");
        }
        // 校验手机号验证码两次发送时间是否大于1分钟
        String randomString = getPhoneCodeTime(dto);

        /* 微信扫码登录绑定手机号发送验证码 */
        // dto.getType() == "binder"则为微信扫码登录绑定手机号发送验证码
        if ("binder".equals(dto.getType())){
            redisTemplate.opsForValue().set(
                    String.format(BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_PHONE,dto.getPhone())
                    ,randomString,5,TimeUnit.MINUTES);
        /* 注册发送手机号验证码 */
        }else {
            // 注册发送手机验证码参数校验
            extracted(dto);
            // 保存手机号验证码到redis中
            redisTemplate.opsForValue().set(
                    String.format(BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_PHONE,dto.getPhone())
                    ,randomString,5,TimeUnit.MINUTES);
        }
        System.err.println(randomString);
        // 调用工具类发送手机验证码
       // SendSmsUtil.send(dto.getPhone(),"你好：你的验证码为："+randomString+"，5分钟内有效！");
    }



    // 获取邮箱验证码
    @Override
    public void getMail(MailCodeDto dto) {
        // 判断邮箱是否为空
        // 判断邮箱格式
        Pattern pattern = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
        if (!pattern.matcher(dto.getMail()).matches()){
            throw new BussinessException("邮箱格式错误！");
        }
        // 判断邮箱是否注册
        Logininfo logininfo = logininfoMapper.getByEmail(dto.getMail());
        if (logininfo != null){
            throw new BussinessException("该邮箱已注册");
        }
        // 校验发送的时间是否大于一分钟
        String eCode = (String) redisTemplate.opsForValue().get(dto.getMail());
        String randomString = "";
        if (StringUtils.isNotBlank(eCode)){
            // 获取剩余时间
            Long time = redisTemplate.getExpire(dto.getMail(), TimeUnit.SECONDS);
            if (time >= 240){
                throw new BussinessException("你已获取过验证码请"+(time - 240) +"秒后重试");
            }
            randomString = StrUtils.getRandomString(4);
        } else {
            randomString = StrUtils.getRandomString(4);
        }
        // 发送验证码

        redisTemplate.opsForValue().set(dto.getMail(),randomString,5,TimeUnit.MINUTES);
        // 发送qq邮件
        EmailUtil.simpleSend("1075053212@qq.com",
                "宠物之家注册邮箱验证码","您的邮箱验证码为:"+randomString+"请在五分钟内使用!");
    }



    private void extracted(PhoneSmsCodeDto dto) {
        String imgCode = (String) redisTemplate.opsForValue().get(dto.getImageCodeKey());
        // 验证参数是否为空
        if (StringUtils.isBlank(dto.getImageCodeKey())){
            throw new BussinessException("uuid不能为空");
        }
        // 校验图形验证码是否正确
        if (StringUtils.isBlank(imgCode) || !imgCode.equalsIgnoreCase(dto.getImageCodeValue())){
            throw new BussinessException("图形验证码输入错误");
        }
        // 校验手机号是否注册
        Logininfo logininfo = logininfoMapper.findByPhone(dto.getPhone());
        if (null != logininfo){
            throw new BussinessException("该手机号已注册");
        }
    }

    @NotNull
    private String getPhoneCodeTime(PhoneSmsCodeDto dto) {
        String vCode = (String) redisTemplate.opsForValue().get(
                String.format(BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_PHONE, dto.getPhone()));
        String randomString = "";
        if (StringUtils.isNotBlank(vCode)){
            Long expire = redisTemplate.getExpire(
                    String.format(BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_PHONE, dto.getPhone()), TimeUnit.SECONDS);
            if (expire >= 240){
                throw new BussinessException("你已获取过验证码请"+ (expire - 240) +"后重试");
            }
            randomString = StrUtils.getRandomString(4);
        } else {
            // 用StrUtils随机生成四位数的验证码
            randomString = StrUtils.getRandomString(4);
        }
        return randomString;
    }
}
